|
This Article Is Taken From The Game Programming MegaSite, A Definitive Resource For Game Developers! |
Now that you can paint opaque figures on the screen (if you can't, get your feet we with the BitBlt tutorial) and you might be wondering how you make an image transparent. This is the tutorial for you. Here, the semi-complex world of alpha-blitting is made wholly transparent (no pun intended). Alpha-blitting is just a fancy word that means painting an image with varying degrees of transparency. Here, I'll be showing you how to do that with BitBlt, although it is quite easy to implement it in DirectDraw.
Here, we'll be making a 256 color image transparent. This consists of a few simple steps. First, we have to make a lookup table. This simply determines what color the resulting pixel should be when the source and destination images are mixed. This is influenced by the varying degrees of transparency, or what alpha-channel is selected. In layman's terms, that is an array that stores the result of a certain color overlayed to another.
For a% = 0 To 255 'Source palette Blue_source% = a% Mod 4 Green_source% = (a% \ 4) Mod 8 Red_source% = a% \ 32 For b% = 0 To 255 Blue_dest% = b% Mod 4 Green_dest% = (b% \ 4) Mod 8 Red_dest% = b% \ 32 'along 7 alpha channels For c% = 1 To 7 Red_combo% = ((pal2(Red_source%) * (8 - c%)) + (pal2(Red_dest%) * c%)) / 8 Blue_combo% = ((pal1(Blue_source%) * (8 - c%)) + (pal1(Blue_dest%) * c%)) / 8 Green_combo% = ((pal2(Green_source%) * (8 - c%)) + (pal2(Green_source%) * c%)) / 8 'the closest color match is going to be in the look-up table trans(a%, b%, c%) = CByte((Blue_combo% \ 85) + (Green_combo% \ 36) * 4 + (Red_combo% \ 36) * 32) Next Next Next
Basically, the c% loop is where the magic happens. Here, the colors are mixed, and the result is stored in the trans array. The nearest color is found through the use of the CByte function.
Now, we have to make a matrix that points to the pixels in the sprite:
With sa .cbElements = 1 .cDims = 2 .Bounds(0).lLbound = 0 .Bounds(0).cElements = bmp.bmHeight .Bounds(1).lLbound = 0 .Bounds(1).cElements = bmp.bmWidthBytes .pvData = bmp.bmBits End With CopyMemory ByVal VarPtrArray(pict), VarPtr(sa), 4
This has to be done three times, for each of the pictures (the buffer, the background and the source). We also have to copy the source bitmap onto the buffer:
For c = 0 To UBound(pict, 1) For r = 0 To UBound(pict, 2) pict(c, r) = pict2(c, r) Next Next
Now, the next big chunk of code is the drawing:
For c = 0 To 107 For r = 0 To 126 'work out the proportion of source vs destination '0 = 100% source '8 = 100% destination Alpha = pict3(c + 108, r) If Alpha > 0 Then 'not transparent If Alpha > 7 Then 'totally opaque pict(c + X, r - Y) = pict3(c, r) Else 'alphablt pict(c + X, r - Y) = trans(pict2(c + X, r - Y), pict3(c, r), Alpha) End If End If Next Next
This goes through the image, pixel-by-pixel to find the appropriate color to draw according to the alpha-channel. Pict, Pict2, and Pict3 are (respectively) the source, destination, and the combination of the two. If the image is opaque, pict is drawn. If it is wholly transparent, pict2 is drawn. Pict3 is the palette for the combination of the two. This draws a bunny head, from my upcoming game. The less you ask, the less scared you'll be (about my game that is).
Now, actually, this is a hacked up version of a tutorial from David Brebner's website, Unlimited Realities. I've simplified it a bit and changed around half of it to be easier to understand and more readable. Coming soon . . . alpha-blitting in 16 million colors.
Oh yeah, make sure to download the source, since I did not include every single line of code as in my other tutorials, to concentrate on the main points that really make alpha-blitting possible.